#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

cv::Mat player;
cv::Mat show_img;

/**
 * @brief The method to find the start location.
 * @param src_image
 * -The image that need to be find the start Point in it.
 * @param player
 * -The image that is used for matching the start loction of the player.
 * @return cv::Point
 * -The Point that represents the start position of the player.
 * @author
 * -1160300719 殷浩然
 */
cv::Point getStartLocation(cv::Mat src_image, cv::Mat player)
{
    cv::Mat dst_image;
    cv::matchTemplate(src_image, player, dst_image, CV_TM_SQDIFF);
    double minValue, maxValue;
    cv::Point minPoint, maxPoint, matchPoint;
    cv::minMaxLoc(dst_image, &minValue, &maxValue, &minPoint, &maxPoint, cv::Mat());
    matchPoint = minPoint;
    cv::Point result;
    result.x = matchPoint.x + (player.cols * 0.5);
    result.y = matchPoint.y + player.rows;
    cv::rectangle(show_img, cv::Rect(matchPoint, cv::Size(player.cols, player.rows)), cv::Scalar(238, 130, 238), 3, 8, 0);
    return result;
}

/**
 * @brief The method to find the target location.
 * @param src_img
 * -The image that need to be find the start Point in it.
 * @param start_x
 * -The param of start Point, help to optimize the algorithm of finding target Point.
 * @return cv::Point
 * -The Point that represents the target position.
 * @author
 * -1160300719 殷浩然
 */
cv::Point getTargetLocation(cv::Mat src_img, int start_x)
{
    cv::Mat blur_img, gray_img;
    int center_x, center_y, max_x;
    cv::GaussianBlur(src_img, blur_img, cv::Size(5, 5), 0);
    cv::Canny(blur_img, gray_img, 1, 10);
    cv::imshow("canny", gray_img);
    if(start_x < 270)
    {
        max_x = 0;
        center_x = 0;
        for(int j=240; j<480; j++)
        {
            uchar* data = gray_img.ptr<uchar>(j);
            for(int i=270; i<540; i++)
            {
                if(data[i] == 255)
                {
                    if(center_x == 0)
                    {
                        center_x = i;
                    }
                    if(i > max_x)
                    {
                        center_y = j;
                        max_x = i;
                    }
                }
            }
        }
    }
    else
    {
        max_x = 0;
        center_x = 0;
        for(int j=240; j<480; j++)
        {
            uchar* data = gray_img.ptr<uchar>(j);
            for(int i=0; i<270; i++)
            {
                if(data[i] == 255)
                {
                    if(center_x == 0)
                    {
                        center_x = i;
                    }
                    if(i > max_x)
                    {
                        center_y = j;
                        max_x = i;
                    }
                }
            }
        }
    }
    cv::Point result(center_x, center_y);
    return result;
}

/**
 * @brief The method that calculate the distance need to be jumped over.
 * @param start_location
 * -The Point that represents the start position of the player.
 * @param target_location
 * -The Point that represents the target position.
 * @return int
 * -The distance need to be jumped over.
 * @author
 * -1160300719 殷浩然
 */
int getDistance(cv::Point start_location, cv::Point target_location)
{
    int A = start_location.x - target_location.x;
    int B = start_location.y - target_location.y;
    cv::line(show_img, start_location, target_location, cv::Scalar(238, 130, 238), 3, 8);
    cv::imshow("结果", show_img);
    return int(pow(pow(A, 2) + pow(B, 2), 0.5));
}

/**
 * @brief The main method.
 * @return The state of the program.
 * @author
 * -1160300719 殷浩然
 */
int main()
{
    /*system("adb shell screencap -p /sdcard/autojump.png");
    system("adb pull /sdcard/autojump.png /home/ian/Documents/Workplace_All/Clion_Workplace/Exercise_1");
    cv::Mat img = cv::imread("autojump.png");
    cv::Mat src_img;
    cv::resize(img, src_img, cv::Size(), 0.5, 0.5);
    cv::imwrite("img.png", src_img);
    std::cout << src_img.size;*/
    while (true)
    {
        system("adb shell screencap -p /sdcard/autojump.png");
        system("adb pull /sdcard/autojump.png /home/ian/Documents/Workplace_All/Clion_Workplace/Exercise_1");
        cv::Mat img = cv::imread("autojump.png");
        player = cv::imread("../template/player.png");
        cv::Mat src_img;
        cv::resize(img, src_img, cv::Size(), 0.5, 0.5);
        cv::resize(img, show_img, cv::Size(), 0.5, 0.5);
        cv::Point start_location = getStartLocation(src_img, player);
        cv::Point target_location = getTargetLocation(src_img, start_location.x);
        int distance = getDistance(start_location, target_location);
        char ch[50] = { " " };
        int rand_x = int(320+rand()%50);
        int rand_y = int(410+rand()%50);
        int time = distance * 2.75;
        sprintf(ch, "adb shell input swipe %d  %d %d %d %d", rand_x, rand_y, rand_x, rand_y, time);
        system(ch);
        /*if(cv::waitKey() != 32)
        {
            break;
        }
        else
        {
            continue;
        }*/
        if(cv::waitKey(1000) != -1)
        {
            break;
        }
    }
    return 0;
}
